package com.shire.bajocontrolredial;

import java.lang.ref.WeakReference;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.provider.ContactsContract;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.RadioGroup.OnCheckedChangeListener;
import android.widget.TextView;
import android.widget.ViewSwitcher;

import com.shire.bajocontrolredial.activity.BCRPreferencesActivity;
import com.shire.bajocontrolredial.utils.MyReceiver;

public class BajoControlRedialActivity extends Activity implements OnClickListener, OnCheckedChangeListener {
	public static final String TAG = "BajoControlRedial";

	private static final int PICK_CONTACT_NUMBER_REQ_CODE = 1;

	private MyReceiver receiver = null;
	private WakeLock wakeLock = null;

	private int selectedService;

	private ViewSwitcher vsMain;
	private EditText etCardNumber;
	private EditText etNumber;

	private TextView tvCallStatus;
	private TextView tvCallCountDown;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);

		selectedService = BCRPreferencesActivity.getLastUsedService(this);

		vsMain = (ViewSwitcher) findViewById(R.id.vsMain);

		final RadioGroup rgService = (RadioGroup) findViewById(R.id.rgService);
		rgService.setOnCheckedChangeListener(this);
		((RadioButton) rgService.findViewById(selectedService)).setChecked(true);

		((Button) findViewById(R.id.bSelectContact)).setOnClickListener(this);
		((Button) findViewById(R.id.bStartCalling)).setOnClickListener(this);
		((Button) findViewById(R.id.bCancelCall)).setOnClickListener(this);

		etCardNumber = (EditText) findViewById(R.id.etCardNumber);
		etCardNumber.setText(BCRPreferencesActivity.getLastCardNumber(this, selectedService));
		etNumber = (EditText) findViewById(R.id.etNumber);
		tvCallStatus = (TextView) findViewById(R.id.tvCallStatus);
		tvCallCountDown = (TextView) findViewById(R.id.tvCountDown);
	}

	@Override
	protected void onDestroy() {
		releaseScreenLock();
		unregisterPhoneStateReciever();
		super.onDestroy();
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		(new MenuInflater(this)).inflate(R.menu.menu_main, menu);
		return super.onCreateOptionsMenu(menu);
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
			case R.id.menuMainPreferences:
				startActivity(new Intent(this, BCRPreferencesActivity.class));
				return true;
		}
		return super.onOptionsItemSelected(item);
	}

	@Override
	public void onClick(View v) {
		switch (v.getId()) {
			case R.id.bStartCalling:
				startCalling();
				break;
			case R.id.bSelectContact:
				pickNumberFromContacts();
				break;
			case R.id.bCancelCall:
				cancelCalling();
				break;
		}
	}

	@Override
	public void onCheckedChanged(RadioGroup group, int checkedId) {
		selectedService = checkedId;
		etCardNumber.setText(BCRPreferencesActivity.getLastCardNumber(this, checkedId));
	}

	private void pickNumberFromContacts() {
		final Intent intent = new Intent(Intent.ACTION_PICK).setType(ContactsContract.CommonDataKinds.Phone.CONTENT_TYPE);
		startActivityForResult(intent, PICK_CONTACT_NUMBER_REQ_CODE);
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
		switch (requestCode) {
			case PICK_CONTACT_NUMBER_REQ_CODE:
				if (resultCode == Activity.RESULT_OK) {
					final Cursor cursor = managedQuery(data.getData(), null, null, null, null);
					if (cursor.moveToFirst()) {
						final String number = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.NUMBER));
						etNumber.setText(number.replaceAll("[ -]", ""));
					}
					cursor.close();
				}
				break;
		}
	}

	private int callCount = 0;
	private CountDownTimer currentCountDown = null;
	private Uri numberUri;
	private int retriesLimit;

	private void startCalling() {
		vsMain.showNext();
		final String serviceNumber;
		if (selectedService == R.id.rBajoControl)
			serviceNumber = getString(R.string.service_bajo_control_number);
		else
			serviceNumber = getString(R.string.service_unica_number);

		BCRPreferencesActivity.saveLastUsedData(this, selectedService, etCardNumber.getText().toString());

		unregisterPhoneStateReciever();

		this.numberUri = Uri.parse(getString(R.string.number_to_call_uri_format, serviceNumber, etCardNumber.getText().toString(), etNumber.getText().toString()));
		this.retriesLimit = BCRPreferencesActivity.getRetriesLimit(this);

		registerReceiver((receiver = new MyReceiver(this)), new IntentFilter(TelephonyManager.ACTION_PHONE_STATE_CHANGED));

		if (BCRPreferencesActivity.isKeepScreenOnEnabled(this)) {
			final PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
			wakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, TAG);
			wakeLock.acquire();
			Log.d(TAG, "Screen lock Acquired");
		} else
			wakeLock = null;

		makeCall();
	}

	private void cancelCalling() {
		releaseScreenLock();
		unregisterPhoneStateReciever();
		if (null != currentCountDown) {
			currentCountDown.cancel();
			currentCountDown = null;
		}
		vsMain.showPrevious();
	}

	private void releaseScreenLock() {
		if (null != wakeLock) {
			wakeLock.release();
			wakeLock = null;
			Log.d(TAG, "Screen lock Released");
		}
	}

	private void unregisterPhoneStateReciever() {
		if (null != receiver) {
			unregisterReceiver(receiver);
			receiver = null;
			Log.d(TAG, "Receiver unregistered");
		}
	}

	public void updateStatus(int callCount) {
		tvCallStatus.setText(getString(R.string.calling_status, etNumber.getText().toString(), callCount));
	}

	public void updateWaitingStatus(int secs) {
		tvCallCountDown.setText(String.valueOf(secs));
	}

	public void callStateIdle() {
		if (null != currentCountDown) {
			currentCountDown.cancel();
			currentCountDown = null;
		}
		if (callCount < retriesLimit) {
			callCount += 1;
			updateStatus(callCount);
			(currentCountDown = new CallCountDown(this, BCRPreferencesActivity.getCallInterval(this))).start();
		} else {
			cancelCalling();
		}
	}

	private void makeCall() {
		final Intent callIntent = new Intent(Intent.ACTION_CALL);
		callIntent.setData(numberUri).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
		startActivity(callIntent);
	}

	static class CallCountDown extends CountDownTimer {
		private final WeakReference<BajoControlRedialActivity> context;

		public CallCountDown(BajoControlRedialActivity context, long millisInFuture) {
			super(millisInFuture, 1000);
			this.context = new WeakReference<BajoControlRedialActivity>(context);
		}

		@Override
		public void onTick(long millisUntilFinished) {
			context.get().updateWaitingStatus((int) (millisUntilFinished / 1000));
		}

		@Override
		public void onFinish() {
			context.get().makeCall();
		}
	}

}